package com.spdb.oa;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.commons.lang.WordUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.spdb.oa.exception.OAException;
import com.spdb.oa.type.ChoiceOpinionFormElement;
import com.spdb.oa.type.LimitedOpinionFormElement;
import com.spdb.oa.type.NextStep;
import com.spdb.oa.type.OpinionFormElement;
import com.spdb.oa.type.SubmitForm;

public class SubmitFormBuilder {
//	public String processId;
//	public String instanceId;
//	public String distributionId;
//	public OpinionFormElement opinion;
//	public ChoiceOpinionFormElement CommonOpinion;
//	public ChoiceOpinionFormElement signOpinion;
//	public ChoiceOpinionFormElement lDSQ;
//	public ChoiceOpinionFormElement opinionType;
//	public ChoiceOpinionFormElement releaseType;
//	public LimitedOpinionFormElement limited;
//	public NextStep nextStep;
	private DocumentBuilderFactory dbf;
	private DocumentBuilder db;
	private SubmitForm sf;
	
	
	
	public SubmitFormBuilder(SubmitForm sf) throws ParserConfigurationException {
		super();
		this.dbf = DocumentBuilderFactory.newInstance();
		this.db = this.dbf.newDocumentBuilder();
		this.sf = sf;
	}

	public String build() throws TransformerException {
		
		
		Document doc = db.newDocument();
		Element parameterElement = doc.createElement("Parameter");
		parameterElement.setAttribute("version", "1.0");
		doc.appendChild(parameterElement);
		
				
		Element processIdElement = doc.createElement("ProcessID");
		processIdElement.appendChild(doc.createCDATASection(sf.processId));
		parameterElement.appendChild(processIdElement);
		Element instanceIdElement = doc.createElement("InstanceID");
		instanceIdElement.appendChild(doc.createCDATASection(sf.instanceId));
		parameterElement.appendChild(instanceIdElement);

		Element distributionIdElement = doc.createElement("DistributionID");
		distributionIdElement.appendChild(doc.createCDATASection(sf.distributionId));
		parameterElement.appendChild(distributionIdElement);

		Element wFFormItemsElement = doc.createElement("WFFormItems");
		parameterElement.appendChild(wFFormItemsElement);

		//�ݲ���Ҫ
//		Element wfFormItemElement = doc.createElement("WFFormItem");
//		wfFormItemsElement.appendChild(wfFormItemElement);
		
		Element opinionFormItemsElement = doc.createElement("OpinionFormItems");
		parameterElement.appendChild(opinionFormItemsElement);
		
		//For opinionFormItems
		Set<Map.Entry<String, OpinionFormElement>> entries = sf.opinionForm.entrySet();
		Iterator<Map.Entry<String, OpinionFormElement>> iter = entries.iterator();
		
		//create opinionFormItem for the following id
		while (iter.hasNext()) {
			Map.Entry<String, OpinionFormElement> entry = iter.next();
			Element opinionElement = doc.createElement("OpinionFormItem");
			
			createOpinionFormItemAttrs(opinionElement, entry.getValue().id,
					entry.getValue().name, entry.getValue().displayName, 
					 entry.getValue().controlType, entry.getValue().required,
					 entry.getValue().visible, entry.getValue().enabled, 
					 entry.getValue().dataType);
			
			if (entry.getKey().equalsIgnoreCase("CommonOpinion") ||
					entry.getKey().equalsIgnoreCase("OpinionType") ||
					entry.getKey().equalsIgnoreCase("SignOpinion") ||
					entry.getKey().equalsIgnoreCase("ReleaseType") ||
					entry.getKey().equalsIgnoreCase("LDSQ")) {
							
				Element opinionItems = doc.createElement("Items");
				opinionElement.appendChild(opinionItems);
				
				ChoiceOpinionFormElement choices = (ChoiceOpinionFormElement) entry.getValue();
				
				ListIterator<ChoiceOpinionFormElement.Chioce> choiceIter = choices.chioces.listIterator();
				while (choiceIter.hasNext()) {
					//make choce item
					ChoiceOpinionFormElement.Chioce choice = choiceIter.next();
					if (choice.selected == true) {
						Element temp = doc.createElement("Item");
						temp.setAttribute("Value", choice.value);
						temp.setAttribute("Selected", "True");
						temp.appendChild(doc.createCDATASection(choice.content));
						opinionItems.appendChild(temp);
					}

				}	
			} else if (entry.getKey().equalsIgnoreCase("Opinion")) {
				opinionElement.appendChild(doc.createCDATASection(entry.getValue().content));
			} else if(entry.getKey().equalsIgnoreCase("Limited")) {
				LimitedOpinionFormElement limitedOpinionFormElement = (LimitedOpinionFormElement) entry.getValue();
				opinionElement.setAttribute("Min", limitedOpinionFormElement.min);
				opinionElement.setAttribute("Max", limitedOpinionFormElement.max);
				opinionElement.setAttribute("DefaultValue", limitedOpinionFormElement.defaultValue);
				opinionElement.appendChild(doc.createCDATASection(limitedOpinionFormElement.content));

			}
			
			if (null != opinionElement)
				opinionFormItemsElement.appendChild(opinionElement);

		}
		
		Element NextStepItemsElement = doc.createElement("NextStepItems");
		parameterElement.appendChild(NextStepItemsElement);
		ListIterator<NextStep> nextStepIter = sf.nextSteps.listIterator();
		
		while (nextStepIter.hasNext()) {
			NextStep ns = nextStepIter.next();
			Element nextStepItemElement = doc.createElement("NextStepItem");
			NextStepItemsElement.appendChild(nextStepItemElement);
			nextStepItemElement.setAttribute("ID", ns.id);
			nextStepItemElement.setAttribute("ActivityID", ns.activityId);
			nextStepItemElement.setAttribute("Name", ns.name);
			nextStepItemElement.setAttribute("DisplayName", ns.displayName);
			nextStepItemElement.setAttribute("DisplayType", ns.displayType);
			nextStepItemElement.setAttribute("Single", ns.single);
			nextStepItemElement.setAttribute("FeedbackFuncationName", ns.feedbackFunctionName);
			nextStepItemElement.setAttribute("FeedbackParameter", ns.feedbackParameter);

			ListIterator<NextStep.User> userIter = ns.users.listIterator();
			Element usersElement = doc.createElement("Users");
			nextStepItemElement.appendChild(usersElement);
			while (userIter.hasNext()) {
				NextStep.User tempUser = userIter.next();
				Element userElement = doc.createElement("User");
				usersElement.appendChild(userElement);
				
				userElement.setAttribute("ID", tempUser.id);
				userElement.setAttribute("UserName", tempUser.userName);
				userElement.setAttribute("DisplayName", tempUser.displayName);
				userElement.setAttribute("UserAccount", tempUser.userAccount);
				userElement.setAttribute("DeptID", tempUser.deptId);
				userElement.setAttribute("DeptName", tempUser.deptName);
				userElement.setAttribute("CompanyID", tempUser.companyId);
				userElement.setAttribute("CompanyName", tempUser.companyName);
				userElement.setAttribute("FeedbackParameter", tempUser.feedbackParameter);
				userElement.appendChild(doc.createCDATASection(tempUser.content));

			}
		}
		
		TransformerFactory transformerFactory = TransformerFactory.newInstance();
		Transformer transformer = transformerFactory.newTransformer();
		DOMSource domSource = new DOMSource(doc);
		StringWriter stringWriter = new StringWriter();
		StreamResult streamResult = new StreamResult(stringWriter);
		transformer.transform(domSource, streamResult);
		
				
		return stringWriter.toString();
	}
	
	private void createOpinionFormItemAttrs(Element e, String id, String name, String displayName, String controlType,
			boolean required, boolean visible, boolean enabled,
			String dataType) {
		e.setAttribute("ID", id);
		e.setAttribute("Name", name);
		e.setAttribute("displayName", displayName);
		e.setAttribute("ControlType", controlType);
		e.setAttribute("Required", WordUtils.capitalize(Boolean.toString(required)));
		e.setAttribute("Visible",  WordUtils.capitalize(Boolean.toString(visible)));
		e.setAttribute("Enabled",  WordUtils.capitalize(Boolean.toString(enabled)));
		e.setAttribute("DataType", dataType);
	}
	
	public static void main(String[] args) throws JsonParseException, IOException, OAException, ParserConfigurationException, TransformerException {
		ObjectMapper om = new ObjectMapper();
		JsonFactory factory = new JsonFactory();
		JsonParser parser = factory.createParser(new File("D:\\Users\\lij70\\workspace\\test\\SubmitWF.json"));
		SubmitForm sf = SubmitForm.readFromJson(parser);
		System.out.println(sf);
		SubmitFormBuilder builder = new SubmitFormBuilder(sf);
		System.out.println(builder.build());
	}
}
